/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-01-31     RT-Thread    first version
 */

#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include "gpio.h"
#include "usart.h"
#include "spi.h"
#include "dma.h"
#include "rtc.h"
#include "can.h"
#include "tim.h"
#include "rc522.h"
#include "periodic.h"
#include <ic.h>
#include "fram.h"
#include "misc.h"


int init_mcu_peripheral(void)
{
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_USART2_UART_Init();
    MX_SPI2_Init();
    MX_USART3_UART_Init();
    MX_SPI1_Init();
    MX_RTC_Init();
    MX_CAN_Init();
    MX_TIM2_Init();

    return RT_EOK;
}
INIT_BOARD_EXPORT(init_mcu_peripheral);     //添加到板级初始化列表



struct rt_thread RfidThread;
char RfidThreadStack[1024];

void RfidThreadEntry(void *param)
{
    static uint8_t IsCardMoveAway = TRUE;
    uint8_t TagType[2], Id[7], FailCnt = 0;

    IcInfoRead();
    SecondAuthSw = SecondAuthStoreInit();
    PwdStoreInit();

    while(1)
    {
        if(PcdRequest(PICC_REQIDL, TagType) == MI_OK)
        {
            while(PcdAnticoll(Id) == MI_OK)
            {
                FailCnt = 0;
                if(IsCardMoveAway == TRUE)
                {
                    IsCardMoveAway = FALSE;
                    uint32_t IdDec = (Id[3] << 24) + (Id[2] << 16) + (Id[1] << 8) + Id[0];
                    rt_kprintf("IC card detected, ID is: 0x%x%x%x%x---%d\n", Id[3], Id[2], Id[1], Id[0], IdDec);

                    if(ReadCardModeTimeout > 0)     //当前处于读卡模式
                    {
                        ReadCardModeTimeout = READ_CARD_MODE_TIMEOUT_SECONDS;
                        uint16_t AckMsgLen;
                        uint8_t Idx = IcInfoMatch(Id);
                        if(Idx == 0xFF)     //在已存储的IC卡信息中未匹配到当前卡
                        {
                            memcpy(UserIcInfo.CardId, Id, 4);
                            IcInfoDeInit(&UserIcInfo);
                            UserIcInfo.AuthState = DRIVER_AUTH_STATE_AUTHED;
                            AckMsgLen = Protocol_CreateReadDriverInfoAckMsg(BleTxDataBuf, &UserIcInfo, 0xFF, 0x01);
                        }
                        else
                        {
                            AckMsgLen = Protocol_CreateReadDriverInfoAckMsg(BleTxDataBuf, &IcInfo[Idx], Idx, 0x01);
                        }

                        BuzzerState = BUZZER_STATE_CARD_DETECTED;
                        ArrayToHexString(BleTxDataBuf, AckMsgLen, ' ', BleTxDataStrBuf);
                        BleSend(BleTxDataBuf, AckMsgLen);
                        rt_kprintf("Currently in reading card mode, card info has been reported to APP\n");
                        rt_kprintf("Reported msg is:\n -- %s --\n", BleTxDataStrBuf);
                    }
                    else    //当前不处于读卡模式
                    {
                        uint8_t Idx = IcInfoVerify(Id);
                        if(Idx != 0xFF)     //IC卡在白名单内
                        {
                            if(SecondAuthSw == PROTOCOL_SECOND_AUTH_STATE_ON)   //二次授权开关已打卡，IC卡虽然在白名单内，也需要向APP发送二次授权申请
                            {
                                if(BleConnTimeout == 0)     //终端与APP蓝牙连接超时
                                {
                                    rt_kprintf("Not connected with APP, second auth cannot be executed!\n");
                                    BuzzerState = BUZZER_STATE_BLE_NOT_CONNECTED;
                                    LedState = LED_STATE_AUTH_FAIL;
                                }
                                else
                                {
                                    uint16_t AckMsgLen = Protocol_CreateSwipeCardResultReportMsg(BleTxDataBuf, PROTOCOL_SWIPE_CARD_RESULT_AUTH_NEED_SECOND_AUTH, 0xFF, IcInfo[Idx].CardId,
                                                                                                 IcInfo[Idx].NameLen, IcInfo[Idx].Name, IcInfo[Idx].IdCardNoLen, IcInfo[Idx].IdCardNo);
                                    ArrayToHexString(BleTxDataBuf, AckMsgLen, ' ', BleTxDataStrBuf);
                                    rt_kprintf("Second auth needed, send request msg to APP:\n");
                                    rt_kprintf("-- %s--\n", BleTxDataStrBuf);
                                    BleSend(BleTxDataBuf, AckMsgLen);
                                    memcpy(&PendingDriver, &IcInfo[Idx], sizeof(DriverInfo_t));     //将待验证的驾驶员信息缓存起来，以备收到APP验证应答后使用。
                                    SecondAuthTimeout = 30;     //二次认证超
                                    BuzzerState = BUZZER_STATE_WAIT_SECOND_AUTH;
                                    LedState = LED_STATE_WAIT_SECOND_AUTH;
                                }
                            }
                            else    //二次授权未打卡，直接认证成功。
                            {
                                rt_kprintf("Authorized card detected\n");
                                BuzzerState = BUZZER_STATE_AUTH_PASS;
                                if(VehState == VEH_STATE_STOP)
                                {
                                    VehStartEnable();
                                    VehState = VEH_STATE_START;
                                    memcpy(UsageRecord.IcCardId, Id, 4);
                                    UsageRecord.NameLen = IcInfo[Idx].NameLen;
                                    memcpy(UsageRecord.Name, IcInfo[Idx].Name, UsageRecord.NameLen);
                                    UsageRecord.DriverIdCardNumLen = IcInfo[Idx].IdCardNoLen;
                                    memcpy(UsageRecord.DriverIdCardNum, IcInfo[Idx].IdCardNo, IcInfo[Idx].IdCardNoLen);
                                    GetCurTime(UsageRecord.Rtc);
                                    UsageRecord.Hour = Hour;
                                    UsageRecord.FlagActive = 0xA5;
                                    UsageRecordStore(&UsageRecord);
                                    UsageRecordPrint(&UsageRecord);
                                    rt_kprintf("Vehicle usage: NOT ALLOWED --> ALLOWED\n");
                                }
                                else
                                {
                                    VehStartDisable();
                                    VehState = VEH_STATE_STOP;
                                    rt_kprintf("Vehicle usage: ALLOWED --> NOT ALLOWED\n");
                                }
                            }
                        }
                        else    //IC卡不在白名单内，未授权
                        {
                            BuzzerState = BUZZER_STATE_AUTH_FAIL;
                            LedState = LED_STATE_AUTH_FAIL;
                            rt_kprintf("Unauthorized card! Vehicle usage not allowed!\n");
                        }
                    }
                }
            }
        }
        else
        {
            if(++FailCnt >= 3)
            {
                FailCnt = 0;
                IsCardMoveAway = TRUE;
            }
        }
        rt_thread_delay(100);
    }
}

int main(void)
{
    int count = 1;

    rt_thread_init(&RfidThread,
                   "RFID thread",
                   RfidThreadEntry,
                   RT_NULL,
                   RfidThreadStack,
                   sizeof(RfidThreadStack),
                   20,
                   100);
    rt_thread_startup(&RfidThread);

    /* 初始化事件集对象*/
    rt_event_init(&BleEvent, "BLE evt", RT_IPC_FLAG_PRIO);



    rt_thread_init(&BleThread,
                   "BLE thread",
                   BleThreadEntry,
                   RT_NULL,
                   BleThreadStack,
                   sizeof(BleThreadStack),
                   20,
                   100);

    rt_thread_startup(&BleThread);

    rt_thread_init(&PeriodicThread,
                   "Period thread",
                   PeriodicThreadEntry,
                   RT_NULL,
                   PeriodicThreadStack,
                   sizeof(PeriodicThreadStack),
                   5,
                   100);
    rt_thread_startup(&PeriodicThread);

    rt_thread_init(&CanTxThread,
                   "Can tx thread",
                   CanTxThreadEntry,
                   RT_NULL,
                   CanTxThreadStack,
                   sizeof(CanTxThreadStack),
                   1,
                   100);
    rt_thread_startup(&CanTxThread);

    while (count++)
    {
//        LOG_D("Hello RT-Thread!");
        RTC_DateTypeDef sDate;
        RTC_TimeTypeDef sTime;
        HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
        HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
//        rt_kprintf("20%02d-%02d-%02d %02d:%02d:%02d\n", sDate.Year, sDate.Month, sDate.Date, sTime.Hours, sTime.Minutes, sTime.Seconds);
        rt_thread_mdelay(1000);
    }

    return RT_EOK;
}

